<?php

class ItemApiRe
{
    const TYPE_KEY_VALUE = 'key_value';
    const TYPE_KEY_ARRAY = 'key_array';
    const TYPE_KEY_MULTI = 'key_multi';

    const API_URL = 'http://rexm.qingcdn.com/api';
    const API_TOKEN = '59a22cd3928ab10db466862710025443';
    const API_RETRY = 1;

    const API_SVC_DEV_URL = 'http://172.18.11.112:11000/api/msgg/';// use in dev
    const API_SVC_URL = 'http://rexm.qingcdn.com/itil/api/msgg/';


    public static function getItem($item = '', $type = self::TYPE_KEY_VALUE)
    {
        $res = array('err' => null, 'data' => array());
        $item_subs = explode(':', $item);
        $item_first_subs = explode('.', $item_subs[0], 2);
        $item_model = $item_first_subs[0];
        $item_key = empty($item_first_subs[1]) ? 'id' : $item_first_subs[1];
        $item_val_strs = explode('|', (empty($item_subs[1]) ? $item_key : $item_subs[1]));
        $item_vals = array();
        foreach ($item_val_strs as $item_val_str) {
            $item_val_subs = explode('.', $item_val_str);
            $num_item_val_subs = count($item_val_subs);
            $item_val = array();
            $item_val['key'] = $item_val_str;
            if ($num_item_val_subs == 1) {
                $item_val['attr'] = $item_val_subs[0];
                $item_val['model'] = null;
            } elseif ($num_item_val_subs >= 2) {
                $item_val['attr'] = $item_val_subs[$num_item_val_subs - 1];
                $item_val['model'] = implode('.', array_slice($item_val_subs, 0, -1));
            }
            $item_vals[] = $item_val;
        }
        switch ($item_model) {
            case 'svr':
            case 'view':
                $params = array();
                $select = array();
                foreach ($item_vals as $item_val) {
                    if ($item_val['model']) {
                        $select[] = $item_val['model'] . '.' . $item_val['attr'];
                    }
                }
                if (!empty($select)) {
                    $params['select'] = $select;
                }
                $res_api = self::apiQuery($item_model . '.get', $params);
                if (!$res_api['err']) {
                    switch ($type) {
                        case self::TYPE_KEY_VALUE:
                            $item_val = $item_vals[0];
                            foreach ($res_api['data'] as $data) {
                                if (empty($data[$item_key])) {
                                    continue;
                                }
                                $v = self::getValue($data, $item_val['model'], $item_val['attr']);
                                $res['data'][$data[$item_key]] = array_shift($v);
                            }
                            break;
                        case self::TYPE_KEY_ARRAY:
                            foreach ($res_api['data'] as $data) {
                                if (empty($data[$item_key])) {
                                    continue;
                                }
                                $item_val_res = array();
                                foreach ($item_vals as $item_val) {
                                    $v = self::getValue($data, $item_val['model'], $item_val['attr']);
                                    if (is_array($v)) {
                                        $item_val_res = array_merge($item_val_res, $v);
                                    } else {
                                        $item_val_res[$item_val['key']] = $v;
                                    }
                                }
                                $res['data'][$data[$item_key]] = $item_val_res;
                            }
                            break;
                    }
                } else {
                    $res['err'] = $res_api['err'];
                }
                break;
            default:
                break;
        }
        return $res;
    }


    private static function apiQuery($method = '', $params = array())
    {
        $res = array('err' => null, 'data' => array());
        $retry = 0;
        while ($retry < self::API_RETRY) {
            $res_post = Curl::post(self::API_URL, self::jsonPost($method, $params), array(CURLOPT_TIMEOUT => 30), array(), 1);
            if (!$res_post['err']) {
                $res_json = json_decode($res_post['content'], true);
                if ($res_json) {
                    if (!empty($res_json['errno'])) {
                        $res['err'] = empty($res_json['errmsg']) ? 'Code:' . $res_json['errno'] : $res_json['errmsg'];
                    } elseif (!empty($res_json['data']) && is_array($res_json['data'])) {
                        $res['data'] = $res_json['data'];
                        $res['err'] = null;
                    } else {
                        $res['err'] = 'Data Unfound';
                    }
                } else {
                    $res['err'] = 'Json Decode Error';
                }
                break;
            } else {
                if (stripos($res_post['err'], 'Operation timed out') == 0) {
                    $res['err'] = 'Operation Timeout';
                    $retry++;
                } else {
                    break;
                }
            }
        }
        return $res;
    }

    private static function jsonPost($method = '', $params = array())
    {
        $postdata = array(
            'token' => self::API_TOKEN,
            'method' => $method,
            'params' => $params,
        );
        return json_encode($postdata);
    }

    private static function getValue(&$data = array(), $model = null, $attr = '', $pre = '')
    {
        if (!$model) {
            if ($attr == '*') {
                $v = array();
                if (self::is_assoc_array($data)) {
                    foreach ($data as $v_k => $v_v) {
                        if (!is_array($v_v)) {
                            $v[$pre . $v_k] = $v_v;
                        }
                    }
                } else {
                    $v[$pre] = $data;
                }
                return $v;
            } else {
                $v = array();
                $v_k = $pre . $attr;
                $v[$v_k] = array();
                if (self::is_assoc_array($data)) {
                    $v[$v_k] = isset($data[$attr]) ? $data[$attr] : null;
                } else {
                    foreach ($data as $data_item) {
                        if (isset($data_item[$attr])) {
                            $v[$v_k][] = $data_item[$attr];
                        }
                    }
                }
                return $v;
            }
        } else {
            $model_subs = explode('.', $model, 2);
            $key = $model_subs[0];
            $model_new = empty($model_subs[1]) ? null : $model_subs[1];
            $pre_new = $pre . $key . '.';
            if (isset($data[$key])) {
                return self::getValue($data[$key], $model_new, $attr, $pre_new);
            } else {
                $k_v = $pre . $model . '.' . $attr;
                return array($k_v => null);
            }
        }
    }

    public static function is_assoc_array($arr)
    {
        return array_keys($arr) !== range(0, count($arr) - 1);
    }

    public static function is_index_array($arr)
    {
        return array_keys($arr) === range(0, count($arr) - 1);
    }

    public static function getSvrStatus($force = false)
    {
        $cacheKey = 'ReSvrStatusList';
        $list = [];
        if (!$force) {
            if (($cache = Yii::app()->cache) && ($cacheValue = $cache->get($cacheKey))) {
                $cacheList = json_decode($cacheValue, true);
                if (is_array($cacheList) && !empty($cacheList)) {
                    $list = $cacheList;
                } else {
                    $force = true;
                }
            } else {
                $force = true;
            }
        }
        if ($force) {
            $res = self::getItem('svr.ip:*', self::TYPE_KEY_ARRAY);
            if (empty($res['err']) && !empty($res['data']) && is_array($res['data'])) {
                foreach ($res['data'] as $key => $info) {
                    $status = 0;
                    $status += (!empty($info['use_status']) && (($info['use_status'] == '2007') || ($info['use_status'] == '2003'))) ? 0 : 1;
                    $status += (!empty($info['fault_status']) && ($info['fault_status'] == '2101')) ? 0 : 2;
                    $status += (!empty($info['hang_status']) && ($info['hang_status'] == '2201')) ? 0 : 4;
                    $ips = explode(',', $key);
                    foreach ($ips as $ip) {
                        if (!empty($ip)) {
                            $list[$ip] = $status;
                        }
                    }
                }
                if (is_array($list) && !empty($list)) {
                    if ($cache = Yii::app()->cache) {
                        $cacheValue = json_encode($list);
                        $cache->set($cacheKey, $cacheValue, 300);
                    }
                } else {
                    $list = array();
                    if ($cache = Yii::app()->cache) {
                        $cacheValue = json_encode($list);
                        $cache->set($cacheKey, $cacheValue, 120);
                    }
                }
            } else {
                $list = array();
                if ($cache = Yii::app()->cache) {
                    $cacheValue = json_encode($list);
                    $cache->set($cacheKey, $cacheValue, 120);
                }
            }
        }
        return $list;
    }

    public static function getSvcInfos($force = false, $ip = null)
    {
        //prepare
        $cacheKey = 'ReSvcInfoList';
        $list = [];
        if (!$force) {
            if (($cache = Yii::app()->cache) && ($cacheValue = $cache->get($cacheKey))) {
                $cacheList = json_decode($cacheValue, true);
                if (is_array($cacheList) && !empty($cacheList)) {
                    $list = $cacheList;
                } else {
                    $force = true;
                }
            } else {
                $force = true;
            }
        }
        if ($force) {
            if (SYS_ENV == 'prod') {
                $url = self::API_SVC_URL . 'svcs';
            } else {
                $url = self::API_SVC_DEV_URL . 'svcs';
            }
            try {
                $cres = Curl::get($url);
                if ($cres['err']) {
                    throw new Exception('CurlErr:' . $cres['err'], 1);
                }
                if (empty($cres['content'])) {
                    throw new Exception('response content empty', 1);
                }
                if (!($resp = json_decode($cres['content'], true))) {
                    throw new Exception('response content decode fail:' . $cres['content'], 1);
                }
                $respCode = isset($resp['code']) ? $resp['code'] : null;
                if ($respCode != 0) {
                    throw new Exception('response respCode abnormal:' . $cres['content'], 1);
                }
                $data = isset($resp['data']) ? $resp['data'] : null;
                if (empty($data) || !is_array($data)) {
                    throw new Exception('data empty', 1);
                }
                foreach ($data as $dip => $info) {
                    $status = 0;
                    $status += (!empty($info['use_status']) && (($info['use_status'] == '2007') || ($info['use_status'] == '2003'))) ? 0 : 1;
                    $status += (!empty($info['fault_status']) && ($info['fault_status'] == '2101')) ? 0 : 2;
                    $status += (!empty($info['hang_status']) && ($info['hang_status'] == '2201')) ? 0 : 4;
                    $list[$dip] = array('svc_sub_types' => $info['svc_sub_types'], 'status' => $status);
                }
                if (is_array($list) && !empty($list)) {
                    if ($cache = Yii::app()->cache) {
                        $cacheValue = json_encode($list);
                        $cache->set($cacheKey, $cacheValue, 300);
                    }
                }
            } catch (Exception $e) {
                $list = array();
                if ($cache = Yii::app()->cache) {
                    $cacheValue = json_encode($list);
                    $cache->set($cacheKey, $cacheValue, 120);
                }
            }
        }
        if (!empty($ip)) {
            $list = array($ip => isset($list[$ip]) ? $list[$ip] : [],);
        }
        //return
        return $list;
    }
}
